﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using ESRI.ArcGIS;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.SystemUI;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.DataSourcesFile;
using ESRI.ArcGIS.Server;
using ESRI.ArcGIS.Framework;
using mapXBase;
using mc_basXcls7Lib;
using mc_basObj7Lib;
using System.Collections;
using mx_MapLibCtrlLib;

namespace ConvertProject
{
    class LinConvert
    {
        //收集已经使用过的子图
        //public List<IStyleGalleryItem> list = new List<IStyleGalleryItem>();

        StyleSymbolMap mStyleSymbolMap = null;
        public void SetStyleSymbolMap(StyleSymbolMap styleSymbolMap)
        {
            mStyleSymbolMap = styleSymbolMap;
        }

        //读取WL信息并转换
        public void readWL(IXGroupLayer grouplayer, string groupname, IMap imap, string savepath, IMapDocument m_MapDocument, string stylepath, int GCScode)
        {
            //MessageBox.Show("读取线类型数据");
            IXMapLayer wllayer = grouplayer.get_Layer(1);

            string layername = groupname.Substring(0, groupname.Length - 3);
            layername = layername + "_Lin";
            //MessageBox.Show(wplayer.LayerType.ToString());
            //获取图层简单要素类
            ISFeatureCls m_sfcls = wllayer.XClass as mcSFeatureCls;

            //查询属性记录  线的总条数 以及objectid
            mcRecordSet recordset = null;
            m_sfcls.Select(null, out recordset);
            if (recordset == null)
            {
                return;
            }
            recordset.MoveFirst();

            IGeomInfo info = null;
            mc_basObj7Lib.IGeometry itry = null;
            mcRecord record = null;
            mcObjectID id = new mcObjectID();

            /************************************************************************/
            /* 生成shapefile文件                                                    */

            ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.Desktop);
            IAoInitialize m_iao = new AoInitializeClass();
            m_iao.Initialize(esriLicenseProductCode.esriLicenseProductCodeEngineGeoDB);

            //const string strFolder = @"D:\MXD1"; 　　//目标文件夹
            string strName = layername;　　//文件名
            const string strShapeFieldName = "Shape";

            //Open the folder to contain the shapefile as a workspace
            IFeatureWorkspace pFWS;
            IWorkspaceFactory pWorkspaceFactory = new ShapefileWorkspaceFactory();
            pFWS = pWorkspaceFactory.OpenFromFile(savepath, 0) as IFeatureWorkspace;

            //Set up a simple fields collection
            ESRI.ArcGIS.Geodatabase.IFields pFields = new FieldsClass();　　//字段
            IFieldsEdit pFieldsEdit = pFields as IFieldsEdit;

            //Make the shape field
            //it will need a geometry definition, with a spatial reference
            ESRI.ArcGIS.Geodatabase.IField pField = new FieldClass();
            IFieldEdit pFieldEdit = pField as IFieldEdit;
            pFieldEdit.Name_2 = strShapeFieldName;
            pFieldEdit.Type_2 = esriFieldType.esriFieldTypeGeometry;

            IGeometryDef pGeometryDef = new GeometryDef();
            IGeometryDefEdit pGeometryDefEdit = pGeometryDef as IGeometryDefEdit;
            pGeometryDefEdit.GeometryType_2 = esriGeometryType.esriGeometryPolyline; //设置shp为线类型*************

            //************设置坐标系 *********
            ISpatialReferenceFactory2 ipSpaRefFact2 = new SpatialReferenceEnvironmentClass();
            IGeographicCoordinateSystem ipGeoCoordSys = new GeographicCoordinateSystemClass();
            if (GCScode != 0)
            {
                ipGeoCoordSys = ipSpaRefFact2.CreateGeographicCoordinateSystem(GCScode);
                pGeometryDefEdit.SpatialReference_2 = ipGeoCoordSys as ISpatialReference;
            }
            else
            {
                pGeometryDefEdit.SpatialReference_2 = new UnknownCoordinateSystem() as ISpatialReference;
            }
            //************设置坐标系 *********

            pFieldEdit.GeometryDef_2 = pGeometryDef;
            pFieldsEdit.AddField(pField);

            //添加字段        
            mcFields fields;
            recordset.GetFields(out fields);
            short numfields = fields.numbfield;
            for (short i = 0; i < numfields; i++)
            {
                mcField field = fields.get_fldEntry(i);
                pField = new FieldClass();
                pFieldEdit = pField as IFieldEdit;
                pFieldEdit.Length_2 = 15;
                pFieldEdit.Name_2 = field.fieldname;
                pFieldEdit.Type_2 = esriFieldType.esriFieldTypeString;
                pFieldsEdit.AddField(pField);
            }

            //Add OID field
            pField = new FieldClass();
            pFieldEdit = pField as IFieldEdit;
            pFieldEdit.Length_2 = 15;
            pFieldEdit.Name_2 = "IDS";
            pFieldEdit.Type_2 = esriFieldType.esriFieldTypeString;
            pFieldsEdit.AddField(pField);

            //Add LinName field
            pField = new FieldClass();
            pFieldEdit = pField as IFieldEdit;
            pFieldEdit.Length_2 = 15;
            pFieldEdit.Name_2 = "LinName";
            pFieldEdit.Type_2 = esriFieldType.esriFieldTypeInteger;
            pFieldsEdit.AddField(pField);

            //Add LinType field
            pField = new FieldClass();
            pFieldEdit = pField as IFieldEdit;
            pFieldEdit.Length_2 = 15;
            pFieldEdit.Name_2 = "LinType";
            pFieldEdit.Type_2 = esriFieldType.esriFieldTypeInteger;
            pFieldsEdit.AddField(pField);

            //Add LinColor field
            pField = new FieldClass();
            pFieldEdit = pField as IFieldEdit;
            pFieldEdit.Length_2 = 15;
            pFieldEdit.Name_2 = "LinColor";
            pFieldEdit.Type_2 = esriFieldType.esriFieldTypeInteger;
            pFieldsEdit.AddField(pField);


            //Add LinWidth field
            pField = new FieldClass();
            pFieldEdit = pField as IFieldEdit;
            pFieldEdit.Length_2 = 15;
            pFieldEdit.Name_2 = "LinWidth";
            pFieldEdit.Type_2 = esriFieldType.esriFieldTypeDouble;
            pFieldsEdit.AddField(pField);

            //Add LinXPar field
            pField = new FieldClass();
            pFieldEdit = pField as IFieldEdit;
            pFieldEdit.Length_2 = 15;
            pFieldEdit.Name_2 = "LinXPar";
            pFieldEdit.Type_2 = esriFieldType.esriFieldTypeSingle;
            pFieldsEdit.AddField(pField);

            //Add LinYPar field
            pField = new FieldClass();
            pFieldEdit = pField as IFieldEdit;
            pFieldEdit.Length_2 = 15;
            pFieldEdit.Name_2 = "LinYPar";
            pFieldEdit.Type_2 = esriFieldType.esriFieldTypeSingle;
            pFieldsEdit.AddField(pField);

            //Add LinSType field
            pField = new FieldClass();
            pFieldEdit = pField as IFieldEdit;
            pFieldEdit.Length_2 = 15;
            pFieldEdit.Name_2 = "LinSType";
            pFieldEdit.Type_2 = esriFieldType.esriFieldTypeInteger;
            pFieldsEdit.AddField(pField);

            //Add LinSClr field
            pField = new FieldClass();
            pFieldEdit = pField as IFieldEdit;
            pFieldEdit.Length_2 = 15;
            pFieldEdit.Name_2 = "LinSClr";
            pFieldEdit.Type_2 = esriFieldType.esriFieldTypeInteger;
            pFieldsEdit.AddField(pField);

            //Add LinLayer field
            pField = new FieldClass();
            pFieldEdit = pField as IFieldEdit;
            pFieldEdit.Length_2 = 15;
            pFieldEdit.Name_2 = "LinLayer";
            pFieldEdit.Type_2 = esriFieldType.esriFieldTypeInteger;
            pFieldsEdit.AddField(pField);

            /**额外添加字段**/
            pField = new FieldClass();
            pFieldEdit = pField as IFieldEdit;
            pFieldEdit.Length_2 = 150;
            pFieldEdit.Name_2 = "GEONAME";
            pFieldEdit.Type_2 = esriFieldType.esriFieldTypeString;
            pFieldsEdit.AddField(pField);

            pField = new FieldClass();
            pFieldEdit = pField as IFieldEdit;
            pFieldEdit.Length_2 = 60;
            pFieldEdit.Name_2 = "SIPNAME";
            pFieldEdit.Type_2 = esriFieldType.esriFieldTypeString;
            pFieldsEdit.AddField(pField);

            pField = new FieldClass();
            pFieldEdit = pField as IFieldEdit;
            pFieldEdit.Length_2 = 15;
            pFieldEdit.Name_2 = "GEOCODE";
            pFieldEdit.Type_2 = esriFieldType.esriFieldTypeInteger;
            pFieldsEdit.AddField(pField);

            pField = new FieldClass();
            pFieldEdit = pField as IFieldEdit;
            pFieldEdit.Length_2 = 8;
            pFieldEdit.Name_2 = "GEOOBJNUM";
            pFieldEdit.Type_2 = esriFieldType.esriFieldTypeString;
            pFieldsEdit.AddField(pField);

            pField = new FieldClass();
            pFieldEdit = pField as IFieldEdit;
            pFieldEdit.Length_2 = 20;
            pFieldEdit.Name_2 = "SHOWLEVEL";
            pFieldEdit.Type_2 = esriFieldType.esriFieldTypeInteger;
            pFieldsEdit.AddField(pField);
            /**额外添加字段**/

            //Create the shapefile

            IFeatureClass featureClass = pFWS.CreateFeatureClass(strName, pFields, null, null, esriFeatureType.esriFTSimple, "Shape", "");

            /************************************************************************************************************************/


            int linecount = recordset.count;
            for (int j = 0; j < linecount; j++)
            {
                /*********************向shapefile文件插入记录***********************/
                IFeatureCursor pInsertFeatureCursor;
                pInsertFeatureCursor = featureClass.Insert(true);

                IFeatureBuffer pInsertFeatureBuffer;
                pInsertFeatureBuffer = featureClass.CreateFeatureBuffer();
                /*********************向shapefile文件插入记录***********************/

                //获取对象的id号   OID
                recordset.GetID(out id);
                //Logfile.WriteLogFile(id.String);
                recordset.MoveNext();
                pInsertFeatureBuffer.set_Value(featureClass.FindField("IDS"), id.String);

                //获取线文件的属性，图形参数和线对应的坐标。
                m_sfcls.Get(id, out itry, out record, out info);


                //图形参数
                ILinInfo lininfo = (ILinInfo)info;
                pInsertFeatureBuffer.set_Value(featureClass.FindField("LinName"), null);
                pInsertFeatureBuffer.set_Value(featureClass.FindField("LinType"), lininfo.linstyID);
                pInsertFeatureBuffer.set_Value(featureClass.FindField("LinColor"), lininfo.outclr1);
                pInsertFeatureBuffer.set_Value(featureClass.FindField("LinWidth"), lininfo.outpenw1);
                pInsertFeatureBuffer.set_Value(featureClass.FindField("LinXPar"), lininfo.xscale);
                pInsertFeatureBuffer.set_Value(featureClass.FindField("LinYPar"), lininfo.yscale);
                pInsertFeatureBuffer.set_Value(featureClass.FindField("LinSType"), lininfo.jointype);
                pInsertFeatureBuffer.set_Value(featureClass.FindField("LinSClr"), lininfo.outclr2);
                pInsertFeatureBuffer.set_Value(featureClass.FindField("LinLayer"), null);

                //线上的点坐标信息
                ILine iline;
                IPoint ipointfrom;
                IPoint ipointto;

                ISegment isegment;
                ISegmentCollection pPath = new PathClass();
                IGeometryCollection pPolyline = new PolylineClass();

                IGeoLine lintry = (IGeoLine)itry;
                mcDots dots = null;
                lintry.Get2Dots(out dots);
                double x, y;
                //Logfile.WriteLogFile(dots.count + "点数");

               // Logfile.WriteLogFile("线号：" + j);
                for (int i = 1; i < dots.count; i++)
                {
                    dots.Get(i - 1, out x, out y);
                    //Logfile.WriteLogFile(x+"   "+y);
                }
                for (int i = 1; i < dots.count; i++)
                {
                    ipointfrom = new ESRI.ArcGIS.Geometry.Point();
                    ipointto = new ESRI.ArcGIS.Geometry.Point();

                    dots.Get(i - 1, out x, out y);
                    ipointfrom.X = x;
                    ipointfrom.Y = y;

                    dots.Get(i, out x, out y);
                    ipointto.X = x;
                    ipointto.Y = y;

                    iline = new ESRI.ArcGIS.Geometry.Line();
                    iline.PutCoords(ipointfrom, ipointto);

                    isegment = (ISegment)iline;
                    pPath.AddSegment(isegment);
                }
                pPolyline.AddGeometry((ESRI.ArcGIS.Geometry.IGeometry)pPath);

                pInsertFeatureBuffer.Shape = (ESRI.ArcGIS.Geometry.IGeometry)pPolyline;

                //线的属性信息
                mcFields fields1;
                record.GetFields(out fields1);
                //每条线对应的属性
                for (int i = 0; i < fields1.numbfield; i++)
                {
                    mcField field = fields.get_fldEntry((short)i);
                    string name = field.fieldname; //属性字段名

                    string strout;                 //属性字段值
                    meFieldType metype;           //属性字段类型
                    short isnull;              //字段是否为空
                    record.CvtFldToString(name, out strout, out metype, out isnull);

                    //if (name.Equals("ID") || name.Equals("maLayer"))
                    //{
                         //pInsertFeatureBuffer.set_Value(featureClass.FindField(name), strout);
                         pInsertFeatureBuffer.set_Value(i+2, strout);

                    //}
                    //  strout 为字段值  name  为字段名
                    //MessageBox.Show(strout + isnull);
                }


                /*********************向shapefile文件插入记录***********************/
                //MessageBox.Show(featureClass.FindField("SubNo") + "");

                //InsertFeature
                pInsertFeatureCursor.InsertFeature(pInsertFeatureBuffer);
                pInsertFeatureCursor.Flush();
                /*********************向shapefile文件插入记录***********************/

            }

            //向MXD中添加图层
            IFeatureLayer pFeatureLayer = new FeatureLayerClass();
            pFeatureLayer.FeatureClass = featureClass;
            pFeatureLayer.Name = strName;
            ILayer ilayer =(ILayer)pFeatureLayer;
            imap.AddLayer((ILayer)ilayer);

            /************************************************************************/
            LinRender(savepath, strName, featureClass, ilayer,stylepath);

            //m_MapDocument.Save();
            //System.GC.Collect();
        }

        //线渲染
        private void LinRender(string savepath, string strName, IFeatureClass featureClass, ILayer ilayer, string stylepath)
        {
            //生成lyr文件
            ILayerFile layerfile = new LayerFileClass();
            string filename = savepath + "\\" + strName + ".lyr";
            layerfile.New(filename);

            //生成渲染对象
            IUniqueValueRenderer render = new UniqueValueRendererClass();
            IQueryFilter queryfileter = new QueryFilterClass();
            IFeatureCursor featurecursor = featureClass.Search(queryfileter, false);

            //创建简单填充
            ILineSymbol simplelinesymbol = new SimpleLineSymbolClass();
            
            //渲染字段设置
            string fillname = "IDS";
            render.FieldCount = 1;
            render.set_Field(0, "IDS");
            
            //颜色
            IRgbColor rgcolor;  

            //得到区数
            int lincount = featureClass.FeatureCount(queryfileter);

            //字段编号
            ESRI.ArcGIS.Geodatabase.IFields fields = new FieldsClass();
            int idsfield = 0;
            int lintypefield = 0;
            int lincolorfield = 0;
            int linwfield = 0;
            int linsubtypefield = 0;
            int linsubcolorfield = 0;

            fields = featurecursor.Fields;
            idsfield = fields.FindField("IDS");
            lintypefield = fields.FindField("LinType");
            lincolorfield = fields.FindField("LinColor");
            linwfield = fields.FindField("LinWidth");
            linsubtypefield = fields.FindField("LinSType");
            linsubcolorfield = fields.FindField("LinSClr");

            //遍历记录
            IFeatureBuffer featurebuff = featureClass.CreateFeatureBuffer();
            for (int i = 0; i < lincount; i++)
            {
                //下移遍历整个dbf
                featurebuff = (IFeatureBuffer)featurecursor.NextFeature();

                //获取各字段值
                string ids = (string)featurebuff.get_Value(idsfield);

                //简单填充
                simplelinesymbol = new SimpleLineSymbolClass();

                //MessageBox.Show(featurebuff.get_Value(lintypefield).ToString());
                int lintype = (int)featurebuff.get_Value(lintypefield);
                int lincolor = (int)featurebuff.get_Value(lincolorfield);
                double linwidth = (double)featurebuff.get_Value(linwfield);
                int linsubtype = (int)featurebuff.get_Value(linsubtypefield);
                int linsubcolor = (int)featurebuff.get_Value(linsubcolorfield);

                //将获取的颜色号转为rgb
                /************************************************************************/
                IXMapColorLib clib = new mcMapColorLibClass();
                //MessageBox.Show(clib.ColorNum + "颜色数量");
                if (lincolor == 0 )
                {
                    lincolor = 1;
                }
                mcMapColor col = clib.get_MapColor(lincolor);
                mcColorRGB rgb = col.RGBValue;
                /************************************************************************/
                //将颜色值赋给简单填充的颜色对象
                rgcolor = new RgbColorClass(); 
                rgcolor.Red = rgb.Red;
                rgcolor.Green = rgb.Green;
                rgcolor.Blue = rgb.Blue;
                if (lintype == 1 && i == 176)
                {
                    rgcolor.Red = 0;
                    rgcolor.Green = 255;
                    rgcolor.Blue = 0;
                }

                if (lintype == 0)
                {
                    //颜色渲染
                    simplelinesymbol.Color = rgcolor;
                    simplelinesymbol.Width = linwidth;

                    render.AddValue(ids, fillname, (ISymbol)simplelinesymbol);
                    render.set_Label(ids, ids);
                    render.set_Symbol(ids, (ISymbol)simplelinesymbol);
                }
                else
                {
                    //style渲染
                    //加载指定的symbol    style文件  名称格式化
                    string stylename = "L-" + String.Format("{0:000}", lintype)+"-"+linsubtype;
                    //string stylename = "L-" + lintype+ "-" + linsubtype;
                    //Logfile.WriteLogFile(ids + " " + stylename);
                    //创建symbol
                    ISymbol symbol = new SimpleLineSymbolClass();
                    bool flagexist = false;

                    symbol = mStyleSymbolMap.GetLineSymbol(stylename);
                    flagexist = (symbol !=null);
                    //Logfile.WriteLogFile(""+flagexist);

                    //如果线型存在就渲染 否则就什么都不做
                    
                    //图案的颜色
                    if (!flagexist)
                    {
                        symbol = new SimpleLineSymbolClass();
                    }                     
                    ILineSymbol linsymbol = (ILineSymbol)symbol;
                    linsymbol.Color = rgcolor;
                    linsymbol.Width = linwidth;

                    render.AddValue(ids, fillname, (ISymbol)linsymbol);
                    render.set_Label(ids, ids);
                    render.set_Symbol(ids, (ISymbol)linsymbol);
                }
            }
            ilayer.Visible = true;
            IGeoFeatureLayer igeofeature = (IGeoFeatureLayer)ilayer;
            IFeatureRenderer featurerender = (IFeatureRenderer)render;
            igeofeature.Name = strName;
            igeofeature.Renderer = featurerender;
            igeofeature.DisplayField = fillname;

            layerfile.ReplaceContents(igeofeature);
            layerfile.Save();
            layerfile.Close();
        }
    }
}
